iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 15
1
自我挑戰組

學JS的心路歷程系列 第 15

學JS的心路歷程 Day15 - 非同步執行

  • 分享至 

  • xImage
  •  

JS 是單執行緒的語言,也就是說同一時間只會執行一行程式,所以如果一段程式執行過久就會造成阻塞 (blocking) 的現象,必須等到它結束後才能執行下一段程式。
舉個例子來說,如果我們今天要買便當,但是老闆說要十分鐘才會好,那難道我們這十分鐘內都不能做任何事情嗎?

當然不是, JS 本身有非同步執行的功能,也是就說我們會先跟這個函式說,你先到旁邊繼續跑,好了在「回來呼叫」我,我先繼續跑其他程式。

有沒有看到熟悉的關鍵字「回來呼叫」,沒錯非同步執行基本上都是利用 callback 達成。

舉個例子來說,我們今天想要某個函式兩秒後在執行,可以這樣寫:

function funA(){
    console.log("funA");
}
function funB(){
    console.log("funB");
}
setTimeout(funA,2000);
funB();
//funB
//funA

但是 callback 作非同步會發現有一個問題,假設我們今天要:

  • 監聽一個按鈕
  • 點擊後延遲一秒
  • 向API發送請求
btn.addEventListener("click",function (){
    setTimeout(function(){
      var oReqSec = new XMLHttpRequest();
      var url = 'https://devche.com/api/speech/data';
      oReqSec.addEventListener("load", functiion(){
          if(this.resp onseText){
              console.log('success');
           }
      });
      oReqSec.open("GET", url);

      oReq.send();
    },1000);
})

有注意到,那恐怖的巢狀結構了嗎?這個我們通常稱為回呼地獄( callback hell )。
但是其可怕之處並不是在於巢狀結構,而是在於如果其中一個 callback 出了問題,不論是自己還是別人都難以 debug 。

這個例子或許比較不好懂,那我們換一個簡單的來看:

doA( function(){
    doB()
    doC(function(){
        doD(function(){
            doE();
        })
    })
})

當今天裡面有個非同步函式出問題的話,有辦法在短時間內找到嗎?
肯定是沒有辦法的吧!

所以很多人都會拿這張波動拳圖片來戲稱 回呼地獄

那到底要怎麼解決這個問題呢?
JS 在 ES6 時候提出了 Promise 語法,雖然底層還是用 callback ,但卻大大解決了這個回呼地獄的問題。
至於怎麼做?我們會在明天一一解析。

參考資料:
你所不知道的 JS 非同步處理與效能
JavaScript - 非同步執行


上一篇
學JS的心路歷程 Day14 - 陣列常見處理方法
下一篇
學JS的心路歷程 Day16-Promise(一)
系列文
學JS的心路歷程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言